package com.photoeditor.demo.model.store.module;


import android.text.TextUtils;

import com.common.base.ComponentContext;
import com.common.base.log.RLog;
import com.common.base.utils.DebugUtil;
import com.common.base.utils.ProcessUtils;
import com.common.base.utils.thread.ThreadPool;
import com.photoeditor.demo.app.TestUser;
import com.photoeditor.demo.model.preference.SpUtils;
import com.photoeditor.demo.statistics.StatisticsConstant;
import com.photoeditor.demo.util.AndroidDevice;
import com.photoeditor.demo.util.FeatureCodeUtil;
import com.photoeditor.demo.util.RegionUtil;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import static com.photoeditor.demo.util.TimeConstant.ONE_HOUR;
import static com.photoeditor.demo.util.TimeConstant.ONE_SEC;

/**
 * 更新最新的服务器地址
 * Created by edward on 17-8-28.
 */

public class ServerUrlUpdater {
    private static final String TAG = "ServerUrlUpdater";
    private static final boolean DEBUG = DebugUtil.isDebuggable() || TestUser.isTestUser();

    private static final String SP_KEY_NEWEST_SERVER_URL = "newest_server_url";
    private static final String SP_KEY_LAST_URL_UPDATE_TIME = "last_server_url_update_time";
    private static final long UPDATE_PERIOD = 4 * ONE_HOUR;

    private static final Object mLock = new Object();

    /**
     * 默认链接，当没有配置或者获取不到时使用这个链接
     */
    private static final String DEFAULT_URL = "http://server.pefacefecret.info:8080/";
    private static final String NEW_SERVER_URL = "http://server3.pefacefecret.info:8080/";

//    private static final String CONFIG_URL = "https://s3-us-west-1.amazonaws.com/superpro-soft/config/config-pe";

    private String mCurrentUrl;

    private boolean mIsLoading;

    private static ServerUrlUpdater sInstance;
    private List<OnServerUrlChangeListener> mOnServerUrlChangeListeners;

    public static synchronized ServerUrlUpdater getInstance() {
        if (sInstance == null) {
            sInstance = new ServerUrlUpdater();
        }
        return sInstance;
    }


    public String getNewestServerUrl() {
        String url = SpUtils.obtain().getString(SP_KEY_NEWEST_SERVER_URL);
        mCurrentUrl = TextUtils.isEmpty(url) ? NEW_SERVER_URL : url;
        updateUrlAsync();
        return mCurrentUrl;
    }

    public synchronized void addOnServerUrlChangeListener(OnServerUrlChangeListener listener) {
        if (mOnServerUrlChangeListeners == null) {
            mOnServerUrlChangeListeners = new CopyOnWriteArrayList<>();
        }
        if (listener != null) {
            mOnServerUrlChangeListeners.add(listener);
        }
    }

    public synchronized void removeOnServerUrlChangeListener(OnServerUrlChangeListener listener) {
        if (mOnServerUrlChangeListeners != null) {
            mOnServerUrlChangeListeners.remove(listener);
        }
    }
    private boolean checkUrl(String serverUrl) {
        try {
            serverUrl = FeatureCodeUtil.addFeatureString(serverUrl);
            URL url = new URL(serverUrl);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setConnectTimeout((int) (5 * ONE_SEC));
            urlConnection.connect();
            if (DEBUG) {
                RLog.d(TAG, "getResponseCode = " + urlConnection.getResponseCode());
            }
            if (urlConnection.getResponseCode() == 200 || urlConnection.getResponseCode() == 304) {
                return true;
            } else {
                if (DEBUG) {
                    RLog.d(TAG, "error code = " + urlConnection.getResponseCode() + serverUrl);
                }
            }
        } catch (IOException ignored) {
            if (DEBUG){
                RLog.d(TAG, "checkUrl exception" + ignored.getMessage());
            }
        }
        return false;
    }

    private List<String> getConfigUrlList() {
        // 无需请求，直接使用默认的两个地址即可
        return new ArrayList<>();
//        com.common.statistics.StatisticsUtils.statisics(StatisticsConstant.UMENG_CUSTOM_EVENT_SERVER_URL_UPDATE,
//                "",
//                "url", StoreOnlineBean.removeQueryString(CONFIG_URL));
//        List<String> serverUrlList = new ArrayList<>();
//        try {
//            long startTime = System.currentTimeMillis();
//            URL url = new URL(CONFIG_URL);
//            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
//            urlConnection.setConnectTimeout((int) (10 * ONE_SEC));
//            urlConnection.connect();
//            int webFileLength = urlConnection.getContentLength();
//            if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
//                InputStream inputStream = urlConnection.getInputStream();
//                long connectLatency = System.currentTimeMillis() - startTime;
//                ByteArrayOutputStream outStream = new ByteArrayOutputStream();
//                byte[] buffer = new byte[1024];
//                int len = 0;
//                while ((len = inputStream.read(buffer)) != -1) {
//                    outStream.write(buffer, 0, len);
//                }
//                String configStr = outStream.toString();
//                if (TextUtils.isEmpty(configStr)) {
//                    return serverUrlList;
//                }
//                String[] urlArr = configStr.split("#");
//                for (String serverUrl : urlArr) {
//                    if (!TextUtils.isEmpty(serverUrl)) {
//                        serverUrlList.add(serverUrl);
//                    }
//                }
//                outStream.close();
//                inputStream.close();
//                statistics(true, startTime, webFileLength, connectLatency, CONFIG_URL, null);
//            } else {
//                statistics(false, 0, 0, 0, CONFIG_URL,
//                        new Exception(String.valueOf(urlConnection.getResponseCode())));
//            }
//        } catch (IOException ignored) {
//            statistics(false, 0, 0, 0, CONFIG_URL, ignored);
//        }
//
//        return serverUrlList;
    }

    private void statistics(boolean success, long startTime, long downloadedFileLength, long connectLatency, String downloadUrl, Exception e) {
        long downloadDuration = System.currentTimeMillis() - startTime;
        float downloadSpeed = (float) (downloadedFileLength * 1.0 / 1024 / (downloadDuration * 1.0 / 1000));
        String event = success ?
                StatisticsConstant.UMENG_CUSTOM_EVENT_SERVER_URL_UPDATE_SUCCESS :
                StatisticsConstant.UMENG_CUSTOM_EVENT_SERVER_URL_UPDATE_ERROR;
        String country = RegionUtil.getSimCountry();
        String model = android.os.Build.BRAND + ":" + android.os.Build.MODEL;
        if (success) {
            com.common.statistics.StatisticsUtils.statisics(event,
                    "",
                    (int) downloadSpeed,
                    "speed", String.valueOf((int) downloadSpeed / 10),
                    "country", country,
                    "model", model,
                    "connectLatency", String.valueOf(connectLatency / 10),
                    "network", AndroidDevice.getNetworkTypeName(),
                    "url", StoreOnlineBean.removeQueryString(downloadUrl));
        } else {
            com.common.statistics.StatisticsUtils.statisics(event,
                    "",
                    0,
                    "error-msg", e.getMessage(),
                    "country", country,
                    "model", model,
                    "network", AndroidDevice.getNetworkTypeName(),
                    "url", StoreOnlineBean.removeQueryString(downloadUrl));
        }
    }

    private void updateUrlAsync() {
        if (mIsLoading || !ProcessUtils.isMainProcess(ComponentContext.getContext())) {
            return;
        }
        mIsLoading = true;
        ThreadPool.runOnNonUIThread(new Runnable() {
            @Override
            public void run() {
                synchronized (mLock) {
                    long lastUpdateTime = SpUtils.obtain().getLong(SP_KEY_LAST_URL_UPDATE_TIME);
                    boolean shouldUpdate = TextUtils.isEmpty(SpUtils.obtain().getString(SP_KEY_NEWEST_SERVER_URL)) ||
                            System.currentTimeMillis() - lastUpdateTime > UPDATE_PERIOD;
                    if (shouldUpdate) {
                        if (DEBUG) {
                            RLog.d(TAG, "updateUrlAsync");
                        }
                        List<String> serverUrls = getConfigUrlList();
                        if (serverUrls.size() == 0) {
                            if (DEBUG) {
                                RLog.d(TAG, "serverUrls.size() == 0");
                            }
                            serverUrls.add(NEW_SERVER_URL);
                            serverUrls.add(DEFAULT_URL);
                        } else {
                            if (DEBUG) {
                                RLog.d(TAG, "serverUrls:" + serverUrls.toString());
                            }
                        }
                        String finalUrl = DEFAULT_URL;
                        for (String url : serverUrls) {
                            if (checkUrl(url)) {
                                if (DEBUG) {
                                    RLog.d(TAG, "finalUrl:" + url);
                                }
                                finalUrl = url;
                                break;
                            }
                        }
                        com.common.statistics.StatisticsUtils.statisics(StatisticsConstant.UMENG_CUSTOM_EVENT_SERVER_URL,
                                "",
                                "url", StoreOnlineBean.removeQueryString(finalUrl));
                        SpUtils.obtain().save(SP_KEY_NEWEST_SERVER_URL, finalUrl);
                        SpUtils.obtain().save(SP_KEY_LAST_URL_UPDATE_TIME, System.currentTimeMillis());
                        if (!TextUtils.equals(finalUrl, mCurrentUrl)) {
                            // 通知更新数据
                            if (mOnServerUrlChangeListeners != null && mOnServerUrlChangeListeners.size() > 0) {
                                for (OnServerUrlChangeListener listener : mOnServerUrlChangeListeners) {
                                    listener.onServerUrlChange(finalUrl);
                                }
                            }
                        }
                    } else {
                        if (DEBUG) {
                            RLog.d(TAG, "no need to update: " + SpUtils.obtain().getString(SP_KEY_NEWEST_SERVER_URL));
                        }
                    }
                    mIsLoading = false;
                }
            }
        });
    }

    public interface OnServerUrlChangeListener {
        void onServerUrlChange(String newUrl);
    }
}
